/**
 * **************************************************************************
 *
 * @说明: 
 * @项目名称: talent-aio-examples-server
 *
 * @author: tanyaowu 
 * @创建时间: 2016年11月17日 下午5:59:24
 *
 * **************************************************************************
 */
package com.lamp.customer;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

import com.lamp.customer.server.LampServerAioHandler;
import com.lamp.customer.server.LampServerAioListener;
import com.sieman.common.protocol.ImPacket;
import com.talent.aio.server.AioServer;
import com.talent.aio.server.ServerGroupContext;
import com.talent.aio.server.intf.ServerAioHandler;
import com.talent.aio.server.intf.ServerAioListener;

/**
 * 
 * @ClassName: LampServerStarter
 * @Description: tcp Server启动工程 服务器启用时加载
 * @author  kangjie1209@126.com
 * @date 2017年1月12日 下午5:01:10
 *
 */
public class LampServerStarter implements ApplicationContextAware{
	
	private Properties pro=null;
	
	private static Logger log = LoggerFactory.getLogger(LampServerStarter.class);
	
	static ServerGroupContext<Object, ImPacket, Object> serverGroupContext = null;

	static AioServer<Object, ImPacket, Object> aioServer = null;

	static ServerAioHandler<Object, ImPacket, Object> aioHandler = null;

	static ServerAioListener<Object, ImPacket, Object> aioListener = null;
	
	static String ip = null;

	static int port = 9321;
	
	//保持三个心跳，如果超时断开链路，同时更新设备状态为离线
	public static int heartbeat = 180;
	
	private static ApplicationContext applicationContext;  

	@Override
	public void setApplicationContext(ApplicationContext arg0)
			throws BeansException {
		LampServerStarter.applicationContext = arg0;
		new Thread(new Runnable() {
			@Override
			public void run() {
				new LampServerStarter();
			}
		}).start();
	}
	
	/**
	 * 
	 *
	 * @author: tanyaowu
	 * @创建时间:　2016年11月17日 下午5:59:24
	 * 
	 */
	public LampServerStarter()
	{
		try {
			loadProperties();
			port = getProInterById("interlamp.socket.server.port","54321");
			heartbeat = getProInterById("interlamp.socket.server.heartbeat","180");
			initServer();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	
    /**
     * 
     * @Title: initServer
     * @Description: 初始化启动 server
     * @throws IOException void
     * @author  kangjie1209@126.com
     * @date 2017年1月12日 下午4:58:19
     */
	public void initServer() throws IOException{
		aioHandler = new LampServerAioHandler();
		aioListener = new LampServerAioListener();
		serverGroupContext = new ServerGroupContext<>(ip, port, aioHandler, aioListener);
		//心跳频率保持,大于此时间内没有心跳数据断开连接
		serverGroupContext.setHeartbeatTimeout(heartbeat * 1000);
		
		aioServer = new AioServer<>(serverGroupContext);
		aioServer.start();
		//下面的代码就是定时打印日志，实际生产环境中可以不用。
//		new Thread(new Runnable()
//		{
//			@Override
//			public void run()
//			{
//				while (true)
//				{
//					try
//					{
//						log.info("[{}]: command stat:{}", SystemTimer.currentTimeMillis(), Json.toJson(CommandStat.commandAndCount));
//						Thread.sleep(5000);
//					} catch (Throwable e)
//					{
//						log.error("", e);
//					}
//				}
//			}
//		}, "t-aio-server-monitor").start();
	}

	
	/**
	 * 加载日志文件
	 */
	public  void loadProperties() throws IOException {
		String cfgfile = "config.properties";
		pro=new Properties();
		InputStream in=null;
		try {
			log.info("开始读取配置文件 file=" + cfgfile);
			Properties props = System.getProperties(); 
			String sysname=props.getProperty("os.name");
			if(sysname!=null&&sysname.toLowerCase().contains("windows")){
				cfgfile="./config.properties";
				in = LampServerStarter.class.getClassLoader().getResourceAsStream(cfgfile);
			}else if(sysname!=null&&sysname.toLowerCase().contains("linux"))
			{
				String path = LampServerStarter.class.getResource("/").toString().replace("file:", "")  
	                    .replace("%20", " ");  
				in=new FileInputStream(path + "config.properties");
			}
			
			pro.load(in);
		}finally 
		{
			try {
				if (in != null)
				in.close();
			} catch (IOException e) {
			}
		}
	}
	
	/**
	 * 获取字符串
	 * @param key
	 * @return
	 */
	public String  getProStrById(String key,String defaultValue)
	{
		return pro.getProperty(key,defaultValue);
	}
	/**
	 * 获得int型配置值
	 * @param key
	 * @return
	 */
	public int  getProInterById(String key,String defaultValue)  throws NumberFormatException
	{
		return Integer.parseInt(pro.getProperty(key,defaultValue));
	}

	
	/** 
	* 清除applicationContext静态变量. 
	*/  
	public static void cleanApplicationContext() {  
		applicationContext = null;  
	}  
	  
	private static void checkApplicationContext() {  
		if (applicationContext == null) {  
		  throw new IllegalStateException("applicaitonContext未注入!");  
		  
		}  
	} 

}
